package net.zdsoft.wpchat.support.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

import net.zdsoft.keel.jdbc.JdbcBasicDao;
import net.zdsoft.keel.jdbc.MapRowMapper;
import net.zdsoft.keel.jdbc.MultiRowMapper;
import net.zdsoft.keel.jdbc.SingleRowMapper;
import net.zdsoft.keel.util.StringUtils;
import net.zdsoft.keel.util.Validators;
import net.zdsoft.wpchat.support.dao.OperatorDao;
import net.zdsoft.wpchat.support.entity.Operator;
import net.zdsoft.wpchat.support.enums.OperatorStateEnum;

/**
 * 后台用户dao实现
 * 
 * @author xuan
 */
@Repository
public class OperatorDaoImpl extends JdbcBasicDao implements OperatorDao {
    private static final String SQL_FIND_BY_OPERATOR_NAME_AND_PWD = "SELECT "
            + "id, login_name, name, password, region_rule, state, creation_time,type FROM "
            + "su_operator WHERE login_name=? AND password=?";
    private static final String SQL_FIND_OPERATOR = "SELECT id, login_name, password, "
            + "name, region_rule, state, creation_time,type FROM su_operator";
    private static final String SQL_FIND_OPERATOR_BY_LOGIN_NAME = "SELECT id, login_name, password, "
            + "name, region_rule, state, creation_time,type FROM su_operator WHERE login_name=?";
    private static final String SQL_FIND_OPERATOR_BY_ID_IN = "SELECT id, login_name, "
            + "password, name, region_rule, state, creation_time,type FROM su_operator WHERE id IN";
    private static final String SQL_DELETE_OPERATOR_BY_ID_IN = "DELETE FROM su_operator WHERE id IN";
    private static final String SQL_INSERT_OPERATOR = "INSERT INTO su_operator(id, login_name, name, "
            + "password, region_rule, state,type,creation_time) VALUES(?,?, ?, ?, ?, ?, ? ,?)";
    private static final String SQL_UPDATE_OPERATOR_INFO = "UPDATE su_operator SET login_name=?, "
            + "name=? ,type=? WHERE id=?";
    private static final String SQL_UPDATE_OPERATOR_STATE = "UPDATE su_operator SET state=? WHERE id=?";
    private static final String SQL_UPDATE_OPERATOR_PASSWORD = "UPDATE su_operator SET password=? WHERE id=?";
    private static final String SQL_FIND_OPERATOR_BY_ID = "SELECT id, login_name, "
            + "password, name, region_rule, state, creation_time,type FROM su_operator WHERE id =?";
    private static final String SQL_FIND_ID_NAME = "select id,name from su_operator";

    @Override
    public Operator findByUserNameAndPwd(String userName, String pwd) {
        return query(SQL_FIND_BY_OPERATOR_NAME_AND_PWD, new Object[] { userName, pwd }, new int[] { Types.CHAR,
                Types.CHAR }, new OperatorSingleRowMapper());
    }

    @Override
    public List<Operator> findAll() {
        return query(SQL_FIND_OPERATOR, new OperatorMultiRowMapper());
    }

    @Override
    public List<Operator> findByIds(String... ids) {
        if (Validators.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return queryForInSQL(SQL_FIND_OPERATOR_BY_ID_IN, null, ids, new OperatorMultiRowMapper());
    }

    @Override
    public void deleteOperator(String... operatorIds) {
        if (Validators.isEmpty(operatorIds)) {
            return;
        }
        updateForInSQL(SQL_DELETE_OPERATOR_BY_ID_IN, null, operatorIds);
    }

    @Override
    public void insertOperator(Operator operator) {
        if (null == operator) {
            return;
        }

        update(SQL_INSERT_OPERATOR,
                new Object[] { operator.getId(), operator.getLoginName(), operator.getName(), operator.getPassword(),
                        operator.getRegionRule(), operator.getState(), operator.getType(), operator.getCreationTime() });
    }

    @Override
    public Operator findByLoginName(String loginName) {
        if (Validators.isEmpty(loginName)) {
            return null;
        }
        return query(SQL_FIND_OPERATOR_BY_LOGIN_NAME, loginName, new OperatorSingleRowMapper());
    }

    @Override
    public void modifyOperator(Operator operator) {
        if (null == operator) {
            return;
        }

        update(SQL_UPDATE_OPERATOR_INFO, new Object[] { operator.getLoginName(), operator.getName(),
                operator.getType(), operator.getId() }, new int[] { Types.VARCHAR, Types.VARCHAR, Types.INTEGER,
                Types.CHAR });
    }

    @Override
    public void updateOperatorState(String operatorId, OperatorStateEnum state) {
        if (Validators.isEmpty(operatorId) || state == null) {
            return;
        }
        update(SQL_UPDATE_OPERATOR_STATE, new Object[] { state.getValue(), operatorId }, new int[] { Types.INTEGER,
                Types.CHAR });
    }

    @Override
    public void updateOperatorPassword(String operatorId, String password) {
        if (Validators.isEmpty(operatorId)) {
            return;
        }
        update(SQL_UPDATE_OPERATOR_PASSWORD, new Object[] { StringUtils.ignoreNull(password), operatorId }, new int[] {
                Types.VARCHAR, Types.CHAR });
    }

    @Override
    public Operator findOperatorById(String id) {
        return query(SQL_FIND_OPERATOR_BY_ID, new Object[] { id }, new OperatorSingleRowMapper());
    }

    @Override
    public Map<String, String> findOperatorsMap(List<String> opratorIdlist) {
        String[] array = opratorIdlist.toArray(new String[opratorIdlist.size()]);
        return queryForInSQL(SQL_FIND_ID_NAME + " WHERE id IN", null, array, new MapRowMapper<String, String>() {

            @Override
            public String mapRowKey(ResultSet rs, int rowNum) throws SQLException {
                return rs.getString("id");
            }

            @Override
            public String mapRowValue(ResultSet rs, int rowNum) throws SQLException {
                return rs.getString("name");
            }
        });
    }

    /**
     * 多条结果集
     * 
     * @author xuan
     */
    private static class OperatorMultiRowMapper implements MultiRowMapper<Operator> {
        @Override
        public Operator mapRow(ResultSet rs, int rowNum) throws SQLException {
            Operator op = new Operator();
            op.setId(StringUtils.ignoreNull(rs.getString("id")).trim());
            op.setLoginName(rs.getString("login_name"));
            op.setName(rs.getString("name"));
            op.setPassword(rs.getString("password"));
            op.setRegionRule(rs.getString("region_rule"));
            op.setState(rs.getInt("state"));
            op.setCreationTime(rs.getTimestamp("creation_time"));
            op.setType(rs.getInt("type"));
            return op;
        }
    }

    /**
     * 单条结果集
     * 
     * @author xuan
     */
    private static class OperatorSingleRowMapper implements SingleRowMapper<Operator> {
        @Override
        public Operator mapRow(ResultSet rs) throws SQLException {
            return new OperatorMultiRowMapper().mapRow(rs, 1);
        }

    }

}
